/**
*
*/
package org.apache.solr.hadoop;
import java.io.IOException;
import java.io.StringReader;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVStrategy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.MapWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
public class CSVMapper extends Mapper<LongWritable, Text, Text, MapWritable> {
private static final Log LOG = LogFactory.getLog(CSVMapper.class);
private Text id = new Text();
private String prefix = null;
private boolean skipHeader = false;
private String[] fieldNames = null;
private CSVStrategy strategy = new CSVStrategy(',', '"',
CSVStrategy.COMMENTS_DISABLED, '\\', false, false, true, true);
@Override
public void setup(Context context) throws IOException, InterruptedException {
super.setup(context);
prefix = context.getConfiguration().get("mapred.task.partition") + "-";
if (context.getConfiguration().getLong("map.input.start", -1) == 0) {
skipHeader = true;
}
String file = ((FileSplit) context.getInputSplit()).getPath().toUri().getPath();
// if (file == null) {
// LOG.warn("no input file name");
// return;
// }
LOG.debug("getting headers for: " + file);
fieldNames = context.getConfiguration().getStrings(CSVIndexer.FIELD_NAMES_KEY + file);
}
MapWritable res = new MapWritable();
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
id.set(prefix + key.toString());
if (key.get() == 0 && skipHeader) { // this is the CSV header line
return;
}
CSVParser parser = new CSVParser(new StringReader(value.toString()), strategy);
String[] fields = null;
try {
fields = parser.getLine();
} catch (Exception e) {
LOG.warn("invalid line: '" + value + "': " + e.toString());
return;
}
if (fieldNames != null && fields.length != fieldNames.length) {
LOG.warn("header.len != line.len: " + value.toString());
return;
}
res.clear();
for (int i = 0; i < fields.length; i++) {
if (fieldNames != null) {
res.put(new Text(fieldNames[i]), new Text(fields[i]));
} else {
res.put(new Text("f" + i), new Text(fields[i]));
}
}
context.write(id, res);
}
}